import {Component, OnInit, AfterViewInit, ElementRef} from '@angular/core';
import {HttpClient, HttpRequest, HttpResponse} from '@angular/common/http';
import {NzMessageService} from 'ng-zorro-antd';
import {UploadFile} from 'ng-zorro-antd/upload';
import {filter} from 'rxjs/operators';
import {HttpService} from '@kylin/http';


@Component({
    templateUrl: './front-page.component.html',
    styleUrls: ['./front-page.component.less']
})
export class FrontPageComponent implements OnInit, AfterViewInit {
    defaultReadingSpeed = 1200;
    trainingTime = 120;
    currentEles = null;
    currentEleIndex = null;
    currentArticleId = null;
    articleDetails = '';
    playerState = false;
    userFileList: UploadFile[] = [];
    recommendedFileList: UploadFile[] = [];
    userUploadState = true;
    recommendedUploadState = true;
    automaticPause = null;
    clearReading = null;
    readerState = false;
    recommendedBookList = {
        data: [],
        pageIndex: 1,
        total: 1
    };
    userBookList = {
        data: [],
        pageIndex: 1,
        total: 1
    };
    reader = {
        speed: this.defaultReadingSpeed,
        content: '',
        startTime: 0,
        pauseTime: 0,
        words: 0
    };


    constructor(private httpClient: HttpClient,
                private msg: NzMessageService,
                private http: HttpService) {
    }

    ngOnInit() {
        this.fetchUserBookList();
        this.fetchRecommendedBookList();
        this.fetchReadingSpeed(true);
    }

    ngAfterViewInit(): void {
        this.keyboardMonitor();
    }

    scroll() {
        const target = this.currentEles[this.currentEleIndex];
        const top = target.offsetTop;
        const scrollEle = document.querySelector('#scroll-content');
        const InitialRollingHeight = document.body.clientHeight / 4;
        if (scrollEle.scrollHeight > scrollEle.clientHeight) {
            if (top > InitialRollingHeight) {
                scrollEle.scrollTo(0, top - InitialRollingHeight);
            }
        }
    }

    resetAutomaticPause() {
        if (this.automaticPause) {
            clearTimeout(this.automaticPause);
        }
    }

    reading() {
        const target = this.currentEles[this.currentEleIndex];
        if (this.currentEleIndex !== 0) {
            this.currentEles[this.currentEleIndex - 1].classList.remove('ant-menu-item-selected');
        }
        if (target) {
            target.classList.add('ant-menu-item-selected');
            this.scroll();
            const speed = Number(this.reader.speed);
            // const speed = 200;
            const currentWords = target.innerText.length;
            this.reader.words = this.reader.words + currentWords;
            const timer = currentWords / speed * 60;
            this.currentEleIndex += 1;
            this.clearReading = setTimeout(() => {
                this.reading();
            }, timer * 1000)
        }
    }

    async start() {
        this.readerState = true;
        this.reader = {
            speed: this.defaultReadingSpeed,
            content: '',
            startTime: 0,
            pauseTime: 0,
            words: 0
        };
        const foo = await this.fetchReadingSpeed();
        if (this.currentEleIndex !== null) {
            this.resetAutomaticPause();
            this.playerState = true;
            this.reader.startTime = new Date().getTime();
            this.reading();
            this.automaticPause = setTimeout(() => {
                this.pause();
            }, 1000 * this.trainingTime)
        } else {
            this.readerState = false;
        }
    }

    pause(init = false) {
        this.readerState = false;
        this.resetAutomaticPause();
        clearTimeout(this.clearReading);
        this.playerState = false;
        this.reader.pauseTime = new Date().getTime();
        if (!init) {
            const takes = (this.reader.pauseTime - this.reader.startTime) / 1000;
            // tslint:disable-next-line:radix
            this.msg.success(`本次训练共阅读${this.reader.words}字,用时${parseInt(takes.toString())}秒`);
        }
        this.http.post('/pause/record', {
            words: this.reader.words,
            viewStartTime: this.reader.startTime,
            viewEndTime: this.reader.pauseTime
        })
            .then(res => {

            })
            .catch(err => {

            })
    }

    keyboardMonitor() {
        document.addEventListener('keyup', (event) => {
            if (event.keyCode === 13) {
                this.playerState ? this.pause() : this.start();
            }
        })
    }

    userBeforeUpload = (file: UploadFile): boolean => {
        this.userFileList = [file];
        this.userHandleUpload();
        return false;
    };
    recommendedBeforeUpload = (file: UploadFile): boolean => {
        this.recommendedFileList = [file];
        this.recommendedHandleUpload();
        return false;
    };


    userHandleUpload(): void {
        const formData = new FormData();
        // tslint:disable-next-line:no-any
        this.userFileList.forEach((file: any) => {
            formData.append('files', file);
        });
        this.userUploadState = false;
        // You can use any AJAX library you like
        const req = new HttpRequest('POST', '/user/upload', formData, {
            // reportProgress: true
        });
        this.httpClient
            .request(req)
            .pipe(filter(e => e instanceof HttpResponse))
            .subscribe(
                () => {
                    this.userUploadState = true;
                    this.userFileList = [];
                    this.msg.success('我的书籍上传成功!');
                    this.fetchUserBookList();
                },
                () => {
                    this.userUploadState = true;
                    this.userFileList = [];
                    this.msg.error('我的书籍上传失败');
                }
            );
    }

    recommendedHandleUpload(): void {
        const formData = new FormData();
        // tslint:disable-next-line:no-any
        this.recommendedFileList.forEach((file: any) => {
            formData.append('files', file);
        });
        this.recommendedUploadState = false;
        // You can use any AJAX library you like
        const req = new HttpRequest('POST', '/recommended/upload', formData, {
            // reportProgress: true
        });
        this.httpClient
            .request(req)
            .pipe(filter(e => e instanceof HttpResponse))
            .subscribe(
                () => {
                    this.recommendedUploadState = true;
                    this.recommendedFileList = [];
                    this.msg.success('推荐书籍上传成功!');
                    this.fetchRecommendedBookList();
                },
                () => {
                    this.recommendedUploadState = true;
                    this.recommendedFileList = [];
                    this.msg.error('推荐书籍上传失败');
                }
            );
    }

    fetchUserBookList() {
        this.http.get('/userBook/pageList', {pageIndex: this.userBookList.pageIndex.toString(), pageSize: '10'})
            .then(res => {
                if (res.status === 200) {
                    this.userBookList.total = res.result.total;
                    this.userBookList.data = res.result.records;
                }
            })
            .catch(err => {

            })
    }

    fetchRecommendedBookList() {
        this.http.get('/recommended/pageList', {
            pageIndex: this.recommendedBookList.pageIndex.toString(),
            pageSize: '10'
        })
            .then(res => {
                if (res.status === 200) {
                    this.recommendedBookList.total = res.result.total;
                    this.recommendedBookList.data = res.result.records;
                }
            })
            .catch(err => {

            })
    }

    fetchReadingSpeed(init = false): Promise<any> {
        return new Promise((resolve, reject) => {
            this.http.get('/speed')
                .then(res => {
                    if (res.status === 200) {
                        if (res.result.pauseCount === 1 || init) {
                            this.reader.speed = res.result.speed;
                            if (!init) {
                                this.msg.success('您已累计完成了一轮训练,阅读速度已经智能调整!');
                            }
                        }

                    } else {
                        this.reader.speed = this.defaultReadingSpeed;
                    }
                    resolve();
                })
                .catch(err => {
                    this.reader.speed = this.defaultReadingSpeed;
                    resolve();
                })
        })
    }

    fetchBookContent(id: string) {
        this.pause(true);
        this.currentArticleId = id;
        this.http.get('/bookContentById', {id})
            .then(res => {
                if (res.status === 200) {
                    this.articleDetails = res.result.bookContent;
                    setTimeout(() => {
                        const targetEle = document.querySelector('.article-details');
                        this.currentEles = targetEle.getElementsByTagName('span');
                        this.currentEleIndex = 0;
                    }, 0)
                }
            })
            .catch(err => {

            })
    }

    userPageIndexChange = ($event) => {
        this.userBookList.pageIndex = $event;
        this.fetchUserBookList();
    };

    recommendedPageIndexChange = ($event) => {
        this.recommendedBookList.pageIndex = $event;
    };

}
